透過網路交換資料的方式(SOAP 和 RESTful API)


Posted by saffran on 2021-02-06

透過網路交換資料的第一種方式:SOAP

SOAP 簡介

SOAP 的全名是 Simple Object Access Protocol,是一個協定,定義了另一種跟 server 溝通的方式

SOAP 的資料交換(request, response)都是透過 XML 的格式

因為 XML 的格式寫起來比較麻煩,因此都會透過一套 Node.js 的 library 叫做 node-soap 讓我更方便地去寫 request

例如:
先建立一個 server,在 server 提供一個 function 叫做 myFunction

client 端連接到 server 後,就可以用 client.MyFunction() 直接呼叫這個 myFunction 函式,這個 function 就是「server 提供給我呼叫的 function」

注意!底層還是一樣是用 XML 在溝通(也就是說,myFunction 會使用 XML 的格式,帶入一些參數)

var soap = require('soap');
  var url = 'http://example.com/wsdl?wsdl';
  var args = {name: 'value'};
  soap.createClient(url, function(err, client) {
      client.MyFunction(args, function(err, result) {
          console.log(result);
      });
  });

透過網路交換資料的第二種方式:SOAP 以外的其他 HTTP API

什麼叫做「其他的」API?

HTTP API 主要分成兩類:

  • 第一類:SOAP
  • 第二類:SOAP 以外的 HTTP API(佔大多數)

「SOAP 以外的 HTTP API」交換資料的方式是:
發送 request 到一個 API 網址,然後就會回傳一個 JSON 格式的 response
例如:PokéAPIreqres

RESTful 到底是什麼?

RESTful 不是一個協定,它只是一種「風格」
(建議你遵循 RESTful 這種風格,但不強制)

RESTful 風格就是:希望你可以好好的去使用這些 HTTP 的 methods

沒有遵循 RESTful 的 API

下圖中的 endpoints (也就是最右邊那欄)就是“沒有遵循” RESTful 風格的

可以看到在上圖的 API,要「刪除使用者」的話,是使用 POST 發送 request 到 /delete_user 這個網址去

這裡你可能會疑問的是:刪除不是要用 DELETE 嗎?

要注意的是:
「刪除」用 DELETE,是一個「良好的習慣」,並不是一個「規範」

只要後端 server 有處理好這件事情,用 POST 一樣也可以模擬「刪除」的功能

因為後端 server 也有 /delete_user 這個網址,所以,就算我是使用 POST,後端也會知道「所有被送到 /delete_user 這個網址的 request 都是要“刪除使用者”的」,並不會跟「新增使用者的 POST」搞混

但是,「不遵循良好習慣」的壞處是:

壞處一:每個工程師都會有不同的命名方式

例如:
「新增使用者」這個功能,有人取名為 /new_user,另一個人取名為 /create_user,另一個人取名為 /create_new_user

壞處二:還是可能會造成混淆,因為用 POST 來刪除是「不具有語意的」

雖然說使用 POST 一樣也可以做到「刪除」的功能,但是「用 DELETE 來刪除」才是具有語意的作法

就像在寫 html 時,所有的標籤都可以用 <div>, <span> 來寫,但這樣是沒有語意的。應該要使用 <session>, <article> 這些有語意的標籤比較好

有遵循 RESTful 的 API

下圖中的 endpoints (也就是最右邊那欄)就是有遵循 RESTful 風格的

RESTful 針對「API 網址、HTTP 動詞(POST, GET, DELETE 這些)」都有一個建議的規範。只要有遵循 RESTful 風格,就可以被稱為是 RESTful API

  • 「新增」就用 POST
  • 「刪除」就用 DELETE
  • 主要的 API 網址會是一個「資源名稱」(會使用複數):/users
  • 「刪除、查詢、更改」某個特定的使用者:/users 後面加上 :id

例如:
reqres 就是一個 RESTful API

透過網路交換資料的第 n 種方式:跳脫 HTTP 的限制

自定義資料交換

其實,有很多 API 是沒有建立在 HTTP 之上的,而是建立在其他的 protocol 上,並使用不同的資料格式來交換資料

各種好用工具及指令

必學指令:curl

用 curl 下載 html 頁面

輸入指令 curl https://github.com/yuwensaf
意思就是:我要發一個 GET 的 request 到 https://github.com/yuwensaf 這個網址(我的 GitHub 頁面)去,因此,得到的 response 就會是這個網頁的 html 程式碼

使用指令 curl https://github.com/yuwensaf > myGithub.html 可以把這個 response 導向到一個新的檔案(myGithub.html),這樣我就成功地把我的 GitHub 頁面下載下來了

打開 myGithub.html,就可以看到我的 GitHub 頁面

用 curl 取得網頁的 Header 內容

加上參數 -I,意思是:我只要 Header,我不要 Body

因此,輸入指令 curl -I https://github.com/yuwensaf 就可以看到 https://github.com/yuwensaf 這個網頁的 Header 內容了

用 curl 來 POST JSON 格式的資料

參考資源 How do I POST JSON data with cURL?

用 curl 來 POST JSON 格式的資料,寫法是這樣:
這裡的 \ 是「換行」的意思

curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"username":"xyz","password":"xyz"}' \
  http://localhost:3000/api/login

拿之前講過的 reqres API 自己改一下:

curl --header "Content-Type: application/json" \
--request POST \
--data '{"name":"Romeo","job":"farmer"}' \
https://reqres.in/api/users

意思就是:
https://reqres.in/api/users 這個網址發一個 POST 的 request,是 JSON 格式的 request:{"name":"Romeo","job":"farmer"}

執行指令後就可以看到回傳的 response,代表我成功建立了一個 Romeo 這個新的 user:

{"name":"Romeo","job":"farmer","id":"887","createdAt":"2020-07-24T13:46:55.365Z"}%

ping, telnet 與 nslookup

nslookup

使用指令 nslookup github.com,就會回傳 github.com 這個 domain 的 IP 地址

ping

使用指令 ping google.com,就會一直丟封包到 google.com,藉此來測試自己是否可以連到 google.com 這台 server(是一個測試的步驟)

如果出現錯誤,那就代表有一方的網路壞掉了

按下 ctrl+C 可以結束指令

telnet 用途一

telnet 有很多用途,最簡單的用途就是:去 ping 一個指定的 port(連到一個指定的 port)
例如:
我用 nslookup github.com 查詢到 github.com 的 IP 地址是 140.82.112.4,我想要針對它的 80 port 去做 telnet(80 是 HTTP 的 port)

就可以輸入指令 telnet 140.82.113.4 80,意思就是:我要連到 140.82.113.4 的 80 port

結果回傳「Connected...」就代表:140.82.113.4 的 80 port 是有打開的

如果等很久都沒有回傳「Connected…」 ,就代表那個 port 沒有開

telnet 用途二

輸入指令 telnet 140.82.113.4 80 後,可以打一些字(傳資料給 github.com)

因為 github.com 是一個 HTTP 的 server,所以可以使用 GET 這個 HTTP method 來取得這個網頁的 html 程式碼

寫法如下:

參考資料 Telnet – Send GET/HEAD HTTP Request

telnet [SERVER] [PORT]
Trying xxx.xxx.xxx.xxx...
Connected to [SERVER].
Escape character is '^]'.
GET [WEB PAGE] HTTP/1.1
HOST: [SERVER]
<Press ENTER>

所以我輸入的指令是:

telnet 140.82.114.3 80                                   
Trying 140.82.114.3...
Connected to lb-140-82-114-3-iad.github.com.
Escape character is '^]'.
GET / HTTP/1.1
HOST: github.com

但是就只有回傳這樣:

HTTP/1.1 301 Moved Permanently
Content-length: 0
Location: https://github.com/

說明:
回傳 301 Moved Permanently 就是轉址的意思,所以它叫你去找 https://github.com/
但用 telnet 應該是沒辦法直接連 https,因為有些憑證相關的東西要處理

telnet 用途三

輸入指令 telnet ptt.cc,意思就是:我要連到 ptt.cc 的 23 port

ptt 這套系統就是基於 telnet 協定

telnet 預設給 ppt 的 port 是 23,因此沒有輸入 port 也可以,telnet ptt.cc 預設就會是 telnet ptt.cc 23

網路的本質

網路的本質就是為了要「溝通」

因為希望溝通可以被「規模化」,因此就需要訂定一些「協定」讓大家去遵循這些標準

而身為網路相關的工程師,就必須去了解這些協定


#Network







Related Posts

序列化操作(JSONObject)

序列化操作(JSONObject)

Deploy express app in Heroku with cleardb

Deploy express app in Heroku with cleardb

Deep Learning on 3D object detection paper 閱讀路徑

Deep Learning on 3D object detection paper 閱讀路徑


Comments